package teamcity.crowd.plugin.loginmodule;
import com.atlassian.crowd.model.user.User;
import com.google.common.base.Optional;
import teamcity.crowd.plugin.PluginCrowdClient;
import teamcity.crowd.plugin.utils.LoggerFactory;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import java.util.Map;
public class CrowdLoginModule implements LoginModule {
private CallbackHandler myCallbackHandler;
private NameCallback myNameCallback;
private PasswordCallback myPasswordCallback;
private Callback[] myCallbacks;
private Subject mySubject;
private PluginCrowdClient pluginCrowdClient;
private LoggerFactory loggerFactory;
private LoggedInUserService loggedInUserService;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
myCallbackHandler = callbackHandler;
myNameCallback = new NameCallback("login:");
myPasswordCallback = new PasswordCallback("password:", false);
myCallbacks = new Callback[]{myNameCallback, myPasswordCallback};
mySubject = subject;
pluginCrowdClient = (PluginCrowdClient) options.get(PluginCrowdClient.class.getName());
loggedInUserService = (LoggedInUserService) options.get(LoggedInUserService.class.getName());
loggerFactory = (LoggerFactory) options.get(LoggerFactory.class.getName());
}
@Override
public boolean login() throws LoginException {
try {
myCallbackHandler.handle(myCallbacks);
} catch (Exception e) {
throw new LoginException(e.toString());
}
final String username = myNameCallback.getName();
final String password = new String(myPasswordCallback.getPassword());
String message = String.format("Attempting to log in with user [%s]", username);
loggerFactory.getServerLogger().debug(message);
Optional<User> possiblyLoggedInUser = pluginCrowdClient.loginUserWithPassword(username, password);
if (possiblyLoggedInUser.isPresent()) {
mySubject.getPrincipals().add(loggedInUserService.updateMembership(possiblyLoggedInUser.get()));
return true;
}
throw new FailedLoginException("Invalid username or password");
}
@Override
public boolean commit() throws LoginException {
return true;
}
@Override
public boolean abort() throws LoginException {
return true;
}
@Override
public boolean logout() throws LoginException {
return true;
}
}